//
// * Copyright (c) 2002-2010 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.graphdb
{

///
/// <summary> * A relationship between two nodes in the graph. A relationship has a start
/// * node, an end node and a <seealso cref="RelationshipType type"/>. You can attach
/// * properties to relationships with the API specified in
/// * <seealso cref="PropertyContainer"/>.
/// * <p>
/// * Relationships are created by invoking the
/// * {@link Node#createRelationshipTo(Node, RelationshipType)
/// * Node.createRelationshipTo()} method on a node as follows:
/// * <p>
/// * <code>
/// * Relationship rel = node.<seealso cref="Node#createRelationshipTo(Node, RelationshipType) createRelationshipTo"/>( otherNode, MyRels.REL_TYPE );
/// * </code>
/// * <p>
/// * <em>Neo4j doesn't support relationships where the start node and end node are the
/// * same.</em>
/// * <p>
/// * The fact that the relationship API gives meaning to {@link #getStartNode()
/// * start} and <seealso cref="getEndNode() end"/> nodes implicitly means that all
/// * relationships have a direction. In the example above, <code>rel</code> would
/// * be directed <i>from</i> <code>node</code> <i>to</i> <code>otherNode</code>. A
/// * relationship's start node and end node and their relation to
/// * <seealso cref="Direction#OUTGOING"/> and <seealso cref="Direction#INCOMING"/> are defined so that
/// * the assertions in the following code are <code>true</code>:
/// * 
/// * <pre>
/// * <code>
/// * <seealso cref="Node"/> a = graphDb.<seealso cref="GraphDatabaseService#createNode() createNode"/>(), b = graphDb.<seealso cref="GraphDatabaseService#createNode() createNode"/>();
/// * <seealso cref="Relationship"/> rel = a.<seealso cref="Node#createRelationshipTo(Node, RelationshipType) createRelationshipTo"/>( b, <seealso cref="RelationshipType MyRels.REL_TYPE"/> );
/// * // Now we have: (a) --- REL_TYPE ---&gt; (b)
/// * 
/// * assert rel.<seealso cref="Relationship#getStartNode() getStartNode"/>().equals( a );
/// * assert rel.<seealso cref="Relationship#getEndNode() getEndNode"/>().equals( b );
/// * assert rel.<seealso cref="Relationship#getNodes() getNodes"/>()[0].equals( a ) &amp;&amp; rel.<seealso cref="Relationship#getNodes() getNodes"/>()[1].equals( b );
/// * </code>
/// * </pre>
/// * 
/// * Even though all relationships have a direction they are equally well
/// * traversed in both directions so there's no need to create duplicate
/// * relationships in the opposite direction (with regard to traversal or
/// * performance).
/// * <p>
/// * Furthermore, Neo4j guarantees that a relationship is never "hanging freely,"
/// * i.e. <seealso cref="getStartNode()"/>, <seealso cref="getEndNode()"/>,
/// * <seealso cref="getOtherNode(Node)"/> and <seealso cref="getNodes()"/> are guaranteed to always
/// * return valid, non-null nodes.
/// * <p>
/// * The id of a relationship is unique, but may not be unique over time since
/// * neo4j reuses deleted ids. See http://wiki.neo4j.org/content/Id_Reuse </summary>
/// 
	public interface Relationship : PropertyContainer
	{
///    
///     <summary> * Returns the unique id of this relationship. Ids are garbage collected
///     * over time so they are only guaranteed to be unique during a specific time
///     * span: if the relationship is deleted, it's likely that a new relationship
///     * at some point will get the old id. This makes relationship ids brittle as
///     * public APIs.
///     *  </summary>
///     * <returns> the id of this node </returns>
///     
		long getId();

///    
///     <summary> * Deletes this relationship. Invoking any methods on this relationship
///     * after <code>delete()</code> has returned is invalid and will lead to
///     * unspecified behavior. </summary>
///     
		void delete();

	// Node accessors
///    
///     <summary> * Returns the start node of this relationship. For a definition of how
///     * start node relates to <seealso cref="Direction directions"/> as arguments to the
///     * <seealso cref="Node#getRelationships() relationship accessors"/> in Node, see the
///     * class documentation of Relationship.
///     *  </summary>
///     * <returns> the start node of this relationship </returns>
///     
		Node getStartNode();

///    
///     <summary> * Returns the end node of this relationship. For a definition of how end
///     * node relates to <seealso cref="Direction directions"/> as arguments to the
///     * <seealso cref="Node#getRelationships() relationship accessors"/> in Node, see the
///     * class documentation of Relationship.
///     *  </summary>
///     * <returns> the end node of this relationship </returns>
///     
		Node getEndNode();

///    
///     <summary> * A convenience operation that, given a node that is attached to this
///     * relationship, returns the other node. For example if <code>node</code> is
///     * a start node, the end node will be returned, and vice versa. This is a
///     * very convenient operation when you're manually traversing the node space
///     * by invoking one of the <seealso cref="Node#getRelationships() getRelationships()"/>
///     * operations on a node. For example, to get the node "at the other end" of
///     * a relationship, use the following:
///     * <p>
///     * <code>
///	 * Node endNode = node.getSingleRelationship( MyRels.REL_TYPE ).getOtherNode ( node );
///	 * </code>
///     * <p>
///     * This operation will throw a runtime exception if <code>node</code> is
///     * neither this relationship's start node nor its end node.
///     *  </summary>
///     * <param name="node"> the start or end node of this relationship </param>
///     * <returns> the other node </returns>
///     * <exception cref="RuntimeException"> if the given node is neither the start nor end
///     *             node of this relationship </exception>
///     
		Node getOtherNode(Node node);

///    
///     <summary> * Returns the two nodes that are attached to this relationship. The first
///     * element in the array will be the start node, the second element the end
///     * node.
///     *  </summary>
///     * <returns> the two nodes that are attached to this relationship </returns>
///     
		Node[] getNodes();

///    
///     <summary> * Returns the type of this relationship. A relationship's type is an
///     * immutable attribute that is specified at Relationship
///     * <seealso cref="Node#createRelationshipTo creation"/>. Remember that relationship
///     * types are semantically equivalent if their
///     * <seealso cref="RelationshipType#name() names"/> are {@link Object#equals(Object)
///     * equal}. This is NOT the same as checking for identity equality using the
///     * == operator. If you want to know whether this relationship is of a
///     * certain type, use the <seealso cref="isType(RelationshipType) isType()"/>
///     * operation.
///     *  </summary>
///     * <returns> the type of this relationship </returns>
///     
		RelationshipType getType();

///    
///     <summary> * Indicates whether this relationship is of the type <code>type</code>.
///     * This is a convenience method that checks for equality using the contract
///     * specified by RelationshipType, i.e. by checking for equal
///     * <seealso cref="RelationshipType#name() names"/>.
///     *  </summary>
///     * <param name="type"> the type to check </param>
///     * <returns> <code>true</code> if this relationship is of the type
///     *         <code>type</code>, <code>false</code> otherwise or if
///     *         <code>null</code> </returns>
///     
		bool isType(RelationshipType type);
	}

}